package com.wmyg.antifake.fabric;

import com.alibaba.fastjson.JSON;
import com.wmyg.antifake.fabric.dto.QueryFabricDto;
import com.wmyg.antifake.fabric.vo.HistoryFabricVo;
import com.wmyg.antifake.fabric.vo.TrackFabricVo;
import lombok.extern.slf4j.Slf4j;
import org.apache.commons.lang3.StringUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.data.redis.core.RedisTemplate;
import org.springframework.stereotype.Repository;

import java.util.ArrayList;

/**
 * @author 王卓逸
 * @program TODO
 * @description TODO
 * @create 2019-05-12
 */
@Slf4j
@Repository
public class FabricDao {

    @Autowired
    RedisTemplate redisTemplate;

    @Autowired
    RabbitDao rabbitDao;

    @Autowired
    AsyncService asyncService;

    public <T> T query(String method, String key, Class<T> tClass) {
        T t = null;
        MqAdaptPo po = new MqAdaptPo();
        po.setMethod(method);
        po.setArgs(new String[]{key});
        po.setIsInvoke(false);
        String resultJsonString = getReply(po, key, false);
        if (!StringUtils.isBlank(resultJsonString)) {
            t = JSON.parseObject(resultJsonString, tClass);
        }
        return t;
    }

    public <T> T queryAndInvoke(String method, String key, Object otherInfo, Class<T> tClass) {
        T t = null;
        MqAdaptPo po = new MqAdaptPo();
        po.setMethod(method);
        po.setArgs(new String[]{key, JSON.toJSONString(otherInfo)});
        po.setIsInvoke(true);
        String resultJsonString = getReply(po, key, true);
        if (!StringUtils.isBlank(resultJsonString)) {
            t = JSON.parseObject(resultJsonString, tClass);
        }
        return t;
    }

    private String getReply(MqAdaptPo po, String key, boolean isInvoke) {
        String resultJsonString = null;
//        po.setIsInvoke(true);
        if (redisTemplate.hasKey(key)) {
            resultJsonString = (String) redisTemplate.opsForValue().get(key);
            asyncService.asyncUpdateRedis(po, key);
            if (isInvoke) {
                resultJsonString = operateData(po, resultJsonString);
            }
        } else {
            resultJsonString = rabbitDao.sendFabricMessage(po);
            if (StringUtils.isBlank(resultJsonString)) {
                return null;
            }
            redisTemplate.opsForValue().set(key, resultJsonString);
        }
        log.info("The result json is {}", resultJsonString);
        return resultJsonString;
    }

    private String operateData(MqAdaptPo po, String before) {
        log.info("The redis data is {}", before);
        String after = before;
        if ("NewQueryMethod".equals(po.getMethod())) {
            QueryFabricDto queryFabricDto = JSON.parseObject(po.getArgs()[1], QueryFabricDto.class);
            TrackFabricVo trackFabricVo = JSON.parseObject(before, TrackFabricVo.class);
            System.out.println(null == trackFabricVo);
            if (null == trackFabricVo) {
                trackFabricVo = new TrackFabricVo();
            }
            HistoryFabricVo history = new HistoryFabricVo();
            history.setUserId(queryFabricDto.getUserId());
            history.setAddress(queryFabricDto.getAddress());
            history.setClientIp(queryFabricDto.getClientIp());
            history.setQueryTime(queryFabricDto.getQueryTime());
            System.out.println(null == trackFabricVo.getHistories());
            if (null == trackFabricVo.getHistories()) {
                trackFabricVo.setHistories(new ArrayList<>());
            }
            trackFabricVo.getHistories().add(history);
            after = JSON.toJSONString(trackFabricVo);
        }
        log.info("The data after operate is {}", after);
        return after;
    }

}
